package com.zuiacsn.java_gobang.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zuiacsn.java_gobang.game.MatchRequest;
import com.zuiacsn.java_gobang.game.MatchResponse;
import com.zuiacsn.java_gobang.game.Matcher;
import com.zuiacsn.java_gobang.game.OnlineUserManager;
import com.zuiacsn.java_gobang.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
@Slf4j
public class MatchAPI extends TextWebSocketHandler {
    @Autowired
    OnlineUserManager onlineUserManager;

    @Autowired
    ObjectMapper objectMapper ;

    @Autowired
    Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 玩家上线 加入到GameHall中
        try {
            // 1. 先获取到当前玩家的身份信息
            User user = (User) session.getAttributes().get("user");
            // 2. 判断用户是否已经登录过, 如果用户登录过 ,就禁止进行登录.
            if(onlineUserManager.getFromGall(user.getUserId()) != null
                    || onlineUserManager.getFromRoom(user.getUserId()) != null) {
                // 当前用户已经登录过了
                MatchResponse matchResponse = new MatchResponse();
                matchResponse.setOk(true);
                matchResponse.setMessage("repeatConnection");
                matchResponse.setReason("禁止多开!");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));
                // 此处直接关闭有点太过激进, 返回一个响应 交给客户端去处理
                // session.close();
                return;
            }
            // 3. 将玩家上线信息保存到 onlineUserManager中 设置玩家状态为在线状态
            onlineUserManager.enterGameHall(user.getUserId(),session);
            log.info("玩家 "+user.getUsername()+" 进入游戏大厅!");
        } catch (Exception e) {
            // 如果直接跳过登录, 直接使用game_hall.html 就会出现user为空的情况 这个时候用户身份不合法,需要返回登录!
            e.printStackTrace();
            MatchResponse matchResponse = new MatchResponse();
            matchResponse.setOk(false);
            matchResponse.setReason("尚未登录,不能进行后续匹配功能!");
            // 通过objectmapper 将返回对象转成string字符串  在通过TextMessage进行一次包装 在进行传输
            // TXMessage 表示一个文本格式的数据包
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 实现处理开始匹配请求和结束匹配请求
        User user = (User) session.getAttributes().get("user");
        // 将json对象转成matchRequest对象
        MatchRequest matchRequest = objectMapper.readValue(message.getPayload(), MatchRequest.class);
        MatchResponse matchResponse = new MatchResponse();
        if(matchRequest.getMessage().equals("startMatch")){
            // 处理请求匹配操作
            // todo 将该请求加入匹配队列
            matcher.add(user);
            // 将匹配请求加入匹配队列之后 就可以返回一个响应给客户端了
            matchResponse.setOk(true);
            matchResponse.setMessage("startMatch");
        }else if(matchRequest.getMessage().equals("stopMatch")){
            // todo 将匹配请求从队列中移除
            matcher.remove(user);
            // 匹配请求从队列中移除之后, 就可以返回一个响应给客户端了
            matchResponse.setOk(true);
            matchResponse.setMessage("stopMatch");
        }else{
            // 非法情况
            matchResponse.setOk(false);
            matchResponse.setReason("非法请求");
        }
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            // 玩家下线 从GameHall中删除
            User user = (User) session.getAttributes().get("user");
            onlineUserManager.exitGameHall(user.getUserId());
            matcher.remove(user);

        } catch (Exception e) {
            System.out.println("[MatchAPI] [handleTransportError] 当前用户未登录!");
/*            // 连接关闭就不能再发响应了
            e.printStackTrace();
            MatchResponse matchResponse = new MatchResponse();
            matchResponse.setOk(false);
            matchResponse.setReason("尚未登录,不能进行后续匹配功能!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));*/
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            // 玩家下线 从GameHall中删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGall(user.getUserId());
            if(tmpSession == session) { // 表示当前的用户不是是尝试双开的用户 可以正常进行退出操作
                onlineUserManager.exitGameHall(user.getUserId());
            }
            matcher.remove(user);

        } catch (Exception e) {
            System.out.println("[MatchAPI] [afterConnectionClosed] 当前用户未登录!");
/*            e.printStackTrace();
            MatchResponse matchResponse = new MatchResponse();
            matchResponse.setOk(false);
            matchResponse.setReason("尚未登录,不能进行后续匹配功能!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));*/
        }
    }
}
